package com.sport.service;

import com.sport.constant.MessageConstant;
import com.sport.context.BaseContext;
import com.sport.exception.BaseException;
import com.sport.exception.JudgeExistException;
import com.sport.exception.RoomFullException;
import com.sport.exception.positionExistException;
import com.sport.mapper.RoomMapper2;
import com.sport.pojo.dto.RoomDto;
import com.sport.pojo.dto.UserListDto;
import com.sport.pojo.entity.Room;
import com.sport.pojo.entity.UandR;
import com.sport.pojo.vo.CampMessageVo;
import com.sport.pojo.vo.RoomVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.locks.Lock;

import static com.sport.constant.CampConstant.RED;
import static com.sport.constant.MessageConstant.*;

@Service
public class RoomService2Impl implements RoomService2 {
    @Autowired
    private RoomMapper2 roomMapper2;
    @Autowired
    private Lock lock;

    @Override
    public List<RoomVo> findRoom(String currentAccount) {
        List<RoomVo> room = roomMapper2.findRoom(currentAccount);
        return room;
    }

    public int createRoom(RoomDto roomDto) {
        roomDto.setRoomId(UUID.randomUUID().toString());
        Room room = new Room();
        BeanUtils.copyProperties(roomDto, room);
        room.setRoomhostId(BaseContext.getCurrentId());
        room.setCreateTime(LocalDateTime.now());
        //自动添加创建房间房主信息到ur中间表，默认房主加入0 红色方
        UandR uandR = new UandR();
        uandR.setUserId(room.getRoomhostId());
        uandR.setRoomId(room.getRoomId());
        uandR.setCamp(0);
        roomMapper2.userIntoRoom(uandR);
        return roomMapper2.createRoom(room);
    }

    @Override
    @Transactional
    public int userIntoRoom(UandR uandR) {
        //互斥锁
        lock.lock();
        try {
            //判断红蓝方是否已满
            if (roomMapper2.campNum(uandR) == roomMapper2.getMaxNum(uandR) / 2) {
                if (uandR.getCamp() == RED) {
                    throw new RoomFullException(RED_ROOM_COUNT_FULL);
                } else {
                    throw new RoomFullException(BLUE_ROOM_COUNT_FULL);
                }
            }
            //判断位置是否被占
            if (roomMapper2.isExist(uandR) != 0) {
                throw new positionExistException(MessageConstant.LOCATION_EXIST);
            }
            int info = roomMapper2.userIntoRoom(uandR);
            int info2 = roomMapper2.addCurrentCount(uandR.getRoomId());
            if(info==0 || info2==0){
                throw new BaseException(ROOM_INTO_ERROR);
            }
            //判断是否满员
            if(roomMapper2.isFull(uandR.getRoomId())==1){
                roomMapper2.updateRoomStatus(uandR.getRoomId());
                return 2;
            }else {
                return 1;
            }
        }finally {
            lock.unlock();
        }

    }

    @Override
    public int userChangeCamp(UandR uandR) {
        //互斥锁
        lock.lock();
        try {
            //判断红蓝方是否已满
            if (uandR.getCamp() != -1) {
                if (roomMapper2.campNum(uandR) == roomMapper2.getMaxNum(uandR) / 2) {
                    if (uandR.getCamp() == RED) {
                        throw new RoomFullException(RED_ROOM_COUNT_FULL);
                    } else {
                        throw new RoomFullException(BLUE_ROOM_COUNT_FULL);
                    }
                }
            }
            //裁判不能加入运动员
            if (roomMapper2.isJudge(uandR) !=0){
                throw new JudgeExistException(MessageConstant.YOU_ARE_JUDGE);
            }
            //判断位置是否被占
            if (roomMapper2.isExist(uandR) != 0) {
                throw new positionExistException(MessageConstant.LOCATION_EXIST);
            }
            //获取原位置
            uandR.setOldImgId(roomMapper2.findImgId(uandR));
            int info =0;
            if (uandR.getCamp() == -1) {
                info = roomMapper2.userNotChangeCamp(uandR);
            }else {
                info=roomMapper2.userChangeCamp(uandR);
            }
            return info;
        }finally {
            lock.unlock();
        }

    }

    @Override
    public RoomVo findRoomByUserId(String userId) {
        RoomVo roomVo = roomMapper2.selectRoomById(userId);
        return roomVo;
    }

    public CampMessageVo showRoomNumber(String roomId) {
        List<UserListDto> templist = roomMapper2.showRoomNumber(roomId);
        List<UserListDto> roomMembers = new ArrayList<>();
        UserListDto judge = null;
        for (UserListDto userListDto : templist) {
            if (userListDto.getCamp() == 2) {
                judge=userListDto;
            } else {
                roomMembers.add(userListDto);
            }
        }
        CampMessageVo campMessageVo = new CampMessageVo();
        campMessageVo.setRoomMembers(roomMembers);
        campMessageVo.setRoomTrail(judge);
        return campMessageVo;
    }

    @Override
    public int exitRoom(UandR uandR) {
        uandR.setImgId(roomMapper2.findImgId(uandR));
        roomMapper2.reduceCount(uandR);
        return roomMapper2.exitRoom(uandR);
    }

    @Override
    @Transactional
    public int destroyRoom(UandR uandR) {
        int info1 =  roomMapper2.deleteUandRByRoomId(uandR.getRoomId());
        int info2 = roomMapper2.deleteRoomByUserId(uandR.getRoomId());
        if(info1==0&&info2==0){
            throw new BaseException(ROOM_DESTROY_ERROR);
        }
        return 1;
    }

    @Override
    public int kickUser(UandR uandR) {
        if(roomMapper2.finduserIdbyImgId(uandR)==null){
            throw new BaseException("此位置无人");
        }
        uandR.setUserId(roomMapper2.finduserIdbyImgId(uandR));
        roomMapper2.reduceCount(uandR);
        return roomMapper2.kickUser(uandR);
    }


    @Override
    public List<RoomVo> findNormalRoom(String currentId) {
        List<RoomVo> room = roomMapper2.findNormalRoom(currentId);
        return room;
    }


}
